var canvas = document.getElementById('canvas'),
	context = canvas.getContext('2d'),

	linearRadio = document.getElementById('linearRadio'),
	easeInRadio = document.getElementById('easeInRadio'),
	easeOutRadio = document.getElementById('easeOutRadio'),
	easeInOutRadio = document.getElementById('easeInOutRadio'),

	animateButton = document.getElementById('animateButton'),

	spritesheet = new Image(),

	runnerCells = [
		{ left: 0, top: 0, width: 205, height: 205 },
		{ left: 205, top: 0, width: 205, height: 205 },
		{ left: 410, top: 0, width: 205, height: 205 },
		{ left: 615, top: 0, width: 205, height: 205 },
		{ left: 820, top: 0, width: 205, height: 205 },
		{ left: 1025, top: 0, width: 205, height: 205 },
		{ left: 1230, top: 0, width: 205, height: 205 },
		{ left: 1435, top: 0, width: 205, height: 205 },
		{ left: 1640, top: 0, width: 205, height: 205 },
		{ left: 1845, top: 0, width: 205, height: 205 },
		{ left: 2050, top: 0, width: 205, height: 205 },
		{ left: 2255, top: 0, width: 205, height: 205 },
		{ left: 2460, top: 0, width: 205, height: 205 },
		{ left: 2665, top: 0, width: 205, height: 205 },
		{ left: 2870, top: 0, width: 205, height: 205 },
		{ left: 3075, top: 0, width: 205, height: 205 },
		{ left: 3280, top: 0, width: 205, height: 205 },
		{ left: 3485, top: 0, width: 205, height: 205 },
		{ left: 3690, top: 0, width: 205, height: 205 },
		{ left: 3895, top: 0, width: 205, height: 205 },
		{ left: 4100, top: 0, width: 205, height: 205 },
		{ left: 4305, top: 0, width: 205, height: 205 },
		{ left: 4510, top: 0, width: 205, height: 205 },
		{ left: 4715, top: 0, width: 205, height: 205 },
		{ left: 4920, top: 0, width: 205, height: 205 },
		{ left: 5125, top: 0, width: 205, height: 205 }
	],

	lastAdvance = 0, // 最近更新过序列帧的时间

	 // 精灵起始位置
	SPRITE_LEFT = canvas.width - runnerCells[0].width,
	SPRITE_TOP = 10,

	PAGEFLIP_INTERVAL = 33, // 频率
	ANIMATION_DURATION = 3900, // 动画时长

	animationTimer = new AnimationTimer(ANIMATION_DURATION, AnimationTimer.makeEaseIn(1)), // 创建一个缓入的计时器

	// 绘制刻度的参数
	LEFT = 1.5,
	RIGHT = canvas.width - runnerCells[0].width,
	BASELINE = 8.5,
	TICK_HEIGHT = 8.5,
	WIDTH = RIGHT - LEFT,

	// 更新序列帧的行为
	runInPlace = {
		execute: function(sprite, context, time){
			var elapsed = animationTimer.getElapsedTime(); // 扭曲过的时间

			if(lastAdvance === 0){ // 跳过第一次
				lastAdvance = elapsed;
			}else if(lastAdvance !== 0 && elapsed - lastAdvance > PAGEFLIP_INTERVAL){ // 如果时间差大于频率更新序列帧和最新更新序列帧进度的时间
				sprite.painter.advance(); // 更新序列帧
				lastAdvance = elapsed; // 更新时间
			}
		}
	},

	// 从右至左的行为
	moveRightToLeft = {
		lastMove: 0, // 最近更新过位移的时间

		reset: function(){
			this.lastMove = 0;
		},

		execute: function(sprite, context, time){
			var elapsed = animationTimer.getElapsedTime(), // 扭曲过的时间
				advanceElapsed = elapsed - this.lastMove; // 时间差

			if(this.lastMove === 0){ // 跳过第一次
				this.lastMove = elapsed;
			}else{
				sprite.left -= (advanceElapsed / 1000) * sprite.velocityX; // 精灵左位置 -= 时间差 * 速度
				this.lastMove = elapsed; // 更新最新移动进度的时间
			}
		}
	},

	// 跑动小人精灵
	sprite = new Sprite('runner', new SpriteSheetPainter(runnerCells), [runInPlace, moveRightToLeft]);

// Functions..................................................................................................

	// 结束动画
	function endAnimation(){
		// 显示动画按钮
		animateButton.style.display = 'inline';
		// 停止计时器
		animationTimer.stop();
		// 序列帧归位
		lastAdvance = 0;
		sprite.painter.cellIndex = 0;
		// 精灵归位
		sprite.left = SPRITE_LEFT;

		// 计时器复位
		animationTimer.reset();
		// 精灵归位
		moveRightToLeft.reset();
	}

	// 开启动画
	function startAnimation(){
		// 隐藏动画按钮
		animateButton.style.display = 'none';
		// 开启计时器
		animationTimer.start();
		// 执行动画
		window.requestNextAnimationFrame(animate);
	}

	// 绘制刻度
	function drawAxis(){
		context.lineWidth = 0.5;
		context.strokeStyle = 'cornflowerblue';

		context.moveTo(LEFT, BASELINE);
		context.lineTo(RIGHT, BASELINE);
		context.stroke();

		for(var i = 0; i <= WIDTH; i += WIDTH / 20){
			context.beginPath();
			context.moveTo(LEFT + i, BASELINE - TICK_HEIGHT / 2);
			context.lineTo(LEFT + i, BASELINE + TICK_HEIGHT / 2);
			context.stroke();
		}

		for(var i = 0; i < WIDTH; i += WIDTH / 4){
			context.beginPath();
			context.moveTo(LEFT + i, BASELINE - TICK_HEIGHT);
			context.lineTo(LEFT + i, BASELINE + TICK_HEIGHT);
			context.stroke();
		}

		context.beginPath();
		context.moveTo(RIGHT, BASELINE - TICK_HEIGHT);
		context.lineTo(RIGHT, BASELINE + TICK_HEIGHT);
		context.stroke();
	}

	// 绘制时间线
	function drawTimeline(){
		var realElapsed = animationTimer.getRealElapsedTime(), // 获取真实逝去的时间
			realPercent = realElapsed / ANIMATION_DURATION; // 获取进度

		context.lineWidth = 0.5;
		context.strokeStyle = 'rgba(0, 0, 255, 0.5)';

		context.beginPath();
		context.moveTo(WIDTH - realPercent * (WIDTH), 0);
		context.lineTo(WIDTH - realPercent * (WIDTH), canvas.height);
		context.stroke();
	}

// Event handlers...........................................................................

	animateButton.onclick = function(e){
		this.value === 'Animate' ? startAnimation() : endAnimation();
	};

	linearRadio.onclick = function(e){
		animationTimer.timeWrap = AnimationTimer.makeLinear(1);
	};

	easeInRadio.onclick = function(e){
		animationTimer.timeWrap = AnimationTimer.makeEaseIn(1);
	};

	easeOutRadio.onclick = function(e){
		animationTimer.timeWrap = AnimationTimer.makeEaseOut(1);
	};

	easeInOutRadio.onclick = function(e){
		animationTimer.timeWrap = AnimationTimer.makeEaseInOut(1);
	};

// Animation...................................................................................

	function animate(){
		if(animationTimer.isRunning()){
			// var elapsed = animationTimer.getElapsedTime(),
			// 	time = + new Date();

			context.clearRect(0, 0, canvas.width, canvas.height);
			sprite.update(context);
			sprite.paint(context);
			drawTimeline();
			drawAxis();

			if(animationTimer.isOver()){
				endAnimation();
				sprite.paint(context);
			}

			window.requestNextAnimationFrame(animate);
		}
	}

// Initialization............................................................................

	spritesheet.src = '../Charpter-06/spritesheet.png';
	sprite.left = SPRITE_LEFT;
	sprite.top = SPRITE_TOP;
	sprite.velocityX = 200; // px/s

	drawAxis();
	spritesheet.onload = function(e){
		sprite.paint(context);
	};